package com.hitqz.robot.biz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.hitqz.robot.api.business.dto.PatrolDevTree;
import com.hitqz.robot.api.business.dto.cvd.CvdSafeExcelDto;
import com.hitqz.robot.api.business.entity.*;
import com.hitqz.robot.api.business.params.QueryPatrolDetailNewParams;
import com.hitqz.robot.api.business.params.QueryPatrolSummaryNewParams;
import com.hitqz.robot.api.business.params.QueryPatrolSummaryParams;
import com.hitqz.robot.api.business.vo.*;
import com.hitqz.robot.biz.mapper.PatrolResultMapper;
import com.hitqz.robot.biz.service.*;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @author wengyx
 * @date 2024/8/7
 */
@Service("patrolResultService")
@AllArgsConstructor
public class PatrolResultServiceIml extends ServiceImpl<PatrolResultMapper, PatrolResultEntity> implements PatrolResultService {

    private final PatrolResultMapper patrolResultMapper;

    private final CvdStoveService cvdStoveService;

    private final CvdStoveHistoryService cvdStoveHistoryService;
    private final TicketsService ticketsService;

    private final GasDetectService gasDetectService;
    private final VisionDetectService visionDetectService;

    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public Page<PatrolResultSummaryVo> summaryPage(Page<PatrolResultSummaryVo> page, QueryPatrolSummaryParams query) {
        return baseMapper.summaryPage(page, query);
    }


    @Override
    public PatrolResultSummaryVo summary(QueryPatrolSummaryParams query) {
        return baseMapper.summary(query);
    }

    @Override
    public List<Tree<String>> buildDeviceTree(String searchName) {
        // 获取所有设备路径（包含两个robotSn）
        List<PatrolDevTree> devPaths = patrolResultMapper.selectAllDistinctDevPaths();
        // 创建根节点 - 全部点位
        TreeNode<String> rootNode = new TreeNode<>();
        rootNode.setId("root");
        rootNode.setParentId("0");
        rootNode.setName("全部点位");
        rootNode.setWeight(0); // 权重可用于排序

        // 创建节点映射表
        Map<String, TreeNode<String>> nodeMap = new HashMap<>();
        List<TreeNode<String>> nodeList = new ArrayList<>();
        nodeList.add(rootNode);
        nodeMap.put("root", rootNode);

        // 创建制氢1和制氢2节点
        TreeNode<String> zq1Node = createRobotNode("ZQ1", "root");
        TreeNode<String> zq2Node = createRobotNode("ZQ2", "root");
        nodeList.add(zq1Node);
        nodeList.add(zq2Node);
        nodeMap.put("ZQ1", zq1Node);
        nodeMap.put("ZQ2", zq2Node);

        // 处理所有设备路径
        for (PatrolDevTree path : devPaths) {
            String devName = path.getDevName();
            String parentId = path.getAllotRobotSn();
            if (!StringUtils.isBlank(searchName) && !devName.contains(searchName)) {
                continue;
            }
            // 逐级构建设备节点

            String nodeName = devName;
            String nodeId = devName;
            if (nodeList.stream().noneMatch(x -> x.getParentId().equals(parentId) && x.getName().equals(nodeId))) {
                TreeNode<String> node = new TreeNode<>();
                node.setId(parentId + nodeId);
                node.setParentId(parentId);
                node.setName(nodeName);


                nodeMap.put(parentId + nodeId, node);
                nodeList.add(node);
            }

        }

        // 构建完整树结构
        return TreeUtil.build(nodeList, "0");
    }

    private TreeNode<String> createRobotNode(String robotSn, String parentId) {
        TreeNode<String> node = new TreeNode<>();
        node.setId(robotSn);
        node.setParentId(parentId);
        node.setName(robotSn);
        node.setExtra(Collections.singletonMap("robotSn", robotSn));
        return node;
    }

    // 获取设备下的检查项
    public List<String> getDeviceItems(String devPath, String robotSn) {
        return patrolResultMapper.selectItemsByDevPath(devPath, robotSn);
    }

    // 查询数值数据
    public List<PatrolResultEntity> getItemValues(
            String robotSn,
            String devName,
            String itemName,
            Date startTime,
            Date endTime) {
        return patrolResultMapper.selectItemValues(robotSn, devName, itemName, startTime, endTime);
    }

    @Override
    public Page<PatrolResultSummaryNewVo> cvdSummaryPage(QueryPatrolSummaryNewParams query) {
        String stoveName = query.getStoveName();
        String productCode = query.getProductCode();
        LocalDateTime startTime = query.getStartTime();
        LocalDateTime endTime = query.getEndTime();
        Integer current = query.getCurrent();
        Integer size = query.getSize();
        Page page = new Page<>(current, size);
        Page<CvdStoveHistoryEntity> historyPage = cvdStoveHistoryService.page(page, Wrappers.<CvdStoveHistoryEntity>lambdaQuery()
                .eq(StringUtils.isNotBlank(stoveName), CvdStoveHistoryEntity::getName, stoveName)
                .eq(StringUtils.isNotBlank(productCode), CvdStoveHistoryEntity::getProductCode, productCode)
                .ge(startTime != null, CvdStoveHistoryEntity::getStartTime, startTime)
                .le(endTime != null, CvdStoveHistoryEntity::getEndTime, endTime)
        );
        return (Page<PatrolResultSummaryNewVo>) historyPage.convert(this::convertToSummaryNewVo);
    }

    private PatrolResultSummaryNewVo convertToSummaryNewVo(CvdStoveHistoryEntity o) {
        PatrolResultSummaryNewVo vo = new PatrolResultSummaryNewVo();
        BeanUtil.copyProperties(o, vo);
        vo.setStoveName(o.getName());
        //状态：0-已完成、1-进行中、2-已结束
        String stoveStatus = "1";
        LocalDateTime eTime = o.getEndTime();
        LocalDateTime aTime = o.getActualEndTime();
        if (eTime != null && aTime != null) {
            if (aTime.isBefore(eTime)) {
                stoveStatus = "2";
            } else {
                stoveStatus = "0";
            }
        }
        vo.setStoveStatus(stoveStatus);
        return vo;
    }

    @Override
    public Page<PatrolResultNewVo> cvdDetailPage(QueryPatrolDetailNewParams query) {
        LocalDateTime startTime = query.getStartTime();
        LocalDateTime endTime = query.getEndTime();
        String ticketsStatus = query.getTicketsStatus();
        String execNo = query.getExecNo();
        Integer current = query.getCurrent();
        Integer size = query.getSize();
        List<Integer> ticketsIds = patrolResultMapper.selectTicketIdsByExecNo(execNo);
        if (CollectionUtil.isNotEmpty(ticketsIds)) {
            Page page = new Page<>(current, size);
            Page<TicketsEntity> ticketsPage = ticketsService.page(page, Wrappers.<TicketsEntity>lambdaQuery()
                    .in(TicketsEntity::getId, ticketsIds)
                    .eq(StringUtils.isNotBlank(ticketsStatus), TicketsEntity::getStatus, ticketsStatus)
                    .ge(startTime != null, TicketsEntity::getCreateTime, startTime)
                    .le(endTime != null, TicketsEntity::getCreateTime, endTime)
                    .orderByAsc(TicketsEntity::getId)
            );
            Page<PatrolResultNewVo> voPage = new Page<>();
            voPage.setTotal(ticketsPage.getTotal());
            voPage.setCurrent(ticketsPage.getCurrent());
            voPage.setSize(ticketsPage.getSize());
            voPage.setRecords(ticketsPage.getRecords().stream().map(x -> convertToPatrolResultNewVo(execNo, x))
                    .collect(Collectors.toList()));
            return voPage;
        }
        return new Page<>();
    }


    @Override
    public List<CvdSafeExcelDto> getCvdSafeEventList(String execNo) {
        CvdStoveHistoryEntity cvdStoveHistory = cvdStoveHistoryService.getOne(Wrappers.<CvdStoveHistoryEntity>lambdaQuery()
                .eq(CvdStoveHistoryEntity::getExecNo, execNo)
        );
        if (cvdStoveHistory == null) {
            return List.of();
        }
        LocalDateTime startTime = cvdStoveHistory.getStartTime();
        LocalDateTime endTime = cvdStoveHistory.getActualEndTime() == null ? cvdStoveHistory.getEndTime() : cvdStoveHistory.getActualEndTime();
        List<CvdSafeExcelDto> cvdSafeEventList = new ArrayList<>();
        //气体检测安全事件
        List<GasDetectEntity> gasList = gasDetectService.list(Wrappers.<GasDetectEntity>lambdaQuery()
                .ge(GasDetectEntity::getCreateTime, startTime)
                .le(GasDetectEntity::getCreateTime, endTime)
        );
        for (GasDetectEntity gas : gasList) {
            CvdSafeExcelDto cvdSafeExcelDto = new CvdSafeExcelDto();
            cvdSafeExcelDto.setType("气体检测");
            cvdSafeExcelDto.setTime(gas.getCreateTime());
            cvdSafeExcelDto.setPos(gas.getPosCode());
            cvdSafeExcelDto.setContent(gas.getContent());
            cvdSafeEventList.add(cvdSafeExcelDto);
        }
        //视觉检测安全事件
        List<VisionDetectEntity> visionList = visionDetectService.list(Wrappers.<VisionDetectEntity>lambdaQuery()
                .ge(VisionDetectEntity::getCreateTime, startTime)
                .le(VisionDetectEntity::getCreateTime, endTime));
        for (VisionDetectEntity vision : visionList) {
            CvdSafeExcelDto cvdSafeExcelDto = new CvdSafeExcelDto();
            cvdSafeExcelDto.setType(vision.getType());
            cvdSafeExcelDto.setTime(vision.getCreateTime());
            cvdSafeExcelDto.setPos(vision.getPosCode());
            cvdSafeExcelDto.setContent(vision.getContent());
            cvdSafeEventList.add(cvdSafeExcelDto);
        }
        cvdSafeEventList.sort(Comparator.comparing(CvdSafeExcelDto::getTime));
        return cvdSafeEventList;
    }

    @Override
    public List<Object> getCvdPatrolList(String execNo) {
        List<PatrolResultEntity> list = patrolResultMapper.selectList(Wrappers.<PatrolResultEntity>lambdaQuery()
                .eq(PatrolResultEntity::getStoveExecNo, execNo)
                .orderByAsc(PatrolResultEntity::getId));

        // 获取唯一itemNames
        List<String> uniqueItemNames = list.stream()
                .collect(Collectors.groupingBy(PatrolResultEntity::getItemName))
                .values()
                .stream()
                .map(group -> group.get(0))
                .sorted(Comparator.comparing(PatrolResultEntity::getId))
                .map(PatrolResultEntity::getItemName)
                .collect(Collectors.toList());

        // 按检查时间分组并转置
        Map<Date, List<PatrolResultEntity>> groupedByTime = list.stream()
                .collect(Collectors.groupingBy(PatrolResultEntity::getCheckTime));

        // 对分组后的键（日期）进行排序
        List<Date> sortedDates = groupedByTime.keySet().stream()
                .sorted()
                .collect(Collectors.toList());

        // 按排序后的日期顺序处理数据
        List<Object> result = new ArrayList<>();
        AtomicInteger index = new AtomicInteger(1);
        for (Date checkTime : sortedDates) {
            List<PatrolResultEntity> items = groupedByTime.get(checkTime);
            Map<String, String> valueMap = items.stream()
                    .collect(Collectors.toMap(PatrolResultEntity::getItemName, PatrolResultEntity::getShowValue));
            List<String> row = new ArrayList<>();
            row.add(String.valueOf(index.getAndIncrement()));
            row.add(sdf.format(checkTime));
            for (String itemName : uniqueItemNames) {
                row.add(valueMap.getOrDefault(itemName, ""));
            }
            result.add(row);
        }

        return result;
    }


    @Override
    public List<List<String>> headForPatrol(String execNo) {
        List<List<String>> headTitles = Lists.newArrayList();
        headTitles.add(Lists.newArrayList("工艺参数报告", "序号"));
        headTitles.add(Lists.newArrayList("工艺参数报告", "日期"));

        List<PatrolResultEntity> list = patrolResultMapper.selectList(Wrappers.<PatrolResultEntity>lambdaQuery()
                .eq(PatrolResultEntity::getStoveExecNo, execNo)
                .orderByAsc(PatrolResultEntity::getId)
        );

        List<String> uniqueItemNames = list.stream()
                .collect(Collectors.groupingBy(PatrolResultEntity::getItemName))
                .values()
                .stream()
                .map(group -> group.get(0))
                .sorted(Comparator.comparing(PatrolResultEntity::getId))
                .map(PatrolResultEntity::getItemName)
                .collect(Collectors.toList());
        for (String name : uniqueItemNames) {
            headTitles.add(Lists.newArrayList("工艺参数报告", name));
        }
        return headTitles;
    }

    private PatrolResultNewVo convertToPatrolResultNewVo(String execNo, TicketsEntity ticketsEntity) {
        PatrolResultNewVo vo = new PatrolResultNewVo();
        vo.setTicketsId(ticketsEntity.getId());
        vo.setTicketsName(ticketsEntity.getName());
        vo.setTicketsStatus(ticketsEntity.getStatus());
        vo.setStartTime(ticketsEntity.getCreateTime());
        vo.setEndTime(ticketsEntity.getFinishTime());

        QueryPatrolSummaryParams query = new QueryPatrolSummaryParams();
        query.setTicketsId(ticketsEntity.getId().intValue());
        query.setStoveExecNo(execNo);
        PatrolResultSummaryVo summaryVo = patrolResultMapper.summary(query);
        vo.setTotalItemNum(summaryVo.getTotalItemNum());
        vo.setWaitItemNum(summaryVo.getWaitItemNum());
        vo.setNormalItemNum(summaryVo.getNormalItemNum());
        vo.setAbnormalItemNum(summaryVo.getAbnormalItemNum());
        vo.setVisionFailedItemNum(summaryVo.getVisionFailedItemNum());
        return vo;
    }


}
